package main

import (
	"fmt"
	"golang.org/x/exp/trace"
	"log"
	"net/http"
	"os"
	"sync"
	"time"
)

func heavyLoad(wg *sync.WaitGroup, iterations int) {
	defer wg.Done()

	for i := 0; i < iterations; i++ {
		_ = fmt.Sprintf("processing %d", i)
	}
	time.Sleep(500 * time.Millisecond)
}

func writeTrace(fr *trace.FlightRecorder) error {
	if !fr.Enabled() {
		return fmt.Errorf("flight recorder not enabled")
	}
	file, err := os.Create("trace.out")
	if err != nil {
		return fmt.Errorf("could not create trace.out file: %w", err)
	}
	defer file.Close()

	_, err = fr.WriteTo(file)
	return err
}

func handler(fr *trace.FlightRecorder) http.HandlerFunc {
	var traceWriter sync.Once
	return func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()

		var wg sync.WaitGroup
		wg.Add(2)

		go heavyLoad(&wg, 100_100)
		go heavyLoad(&wg, 10_000_100)

		wg.Wait()

		diff := time.Since(start)

		// 放在中间件里
		if diff > 300*time.Millisecond {
			traceWriter.Do(func() {
				if err := writeTrace(fr); err != nil {
					log.Printf("failed to write trace: %v", err)
					return
				}

			})
		}

		fmt.Fprintf(w, "worked for %f seconds", diff.Seconds())
	}
}

// go tool trace trace.out
func main() {
	fr := trace.NewFlightRecorder()
	if err := fr.Start(); err != nil {
		log.Fatal(err)
	}
	defer fr.Stop()

	http.Handle("/", handler(fr))
	http.ListenAndServe(":8080", nil)
}
